package taskTracker.ui.lite;

import java.util.Enumeration;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;

import taskTracker.Interval;
import taskTracker.Project;
import taskTracker.Task;
import taskTracker.util.Helper;

/**
 * A dialog that lets the user chooses a Project and a Task to log time to.
 * It also allows him to enter an optional comment.
 * He can also choose a time after which an alert is shown to him.
 * @author aseldawy
 *
 */
public class LogTimeForm extends Form {

	/**Command for accepting input*/
	final Command cmdOk = new Command("Ok", Command.OK, 1);

	/**Command for cancellation*/
	final Command cmdCancel = new Command("Cancel", Command.BACK, 2);
	
	/**A combo box for choosing a list*/
	private final ChoiceGroup cmbProject = new ChoiceGroup("Project", ChoiceGroup.POPUP);
	
	/**A combo box for choosing a task*/
	private final ChoiceGroup cmbTask = new ChoiceGroup("Task", ChoiceGroup.POPUP);
	
	/**A note associated with logged time entry*/
	private final TextField txtComment = new TextField("Comment", "", 255, TextField.ANY);

	/**A timer used to populate tasks from projects in background*/
	private Timer timer = new Timer();
	
	/**Time to wait till the next alert*/
	private final ChoiceGroup cmbAlertAfter = new ChoiceGroup("Alert me after", ChoiceGroup.POPUP, new Interval[] {
			Interval.minutes(2), Interval.minutes(5), Interval.minutes(10), Interval.minutes(15),
			Interval.minutes(30), Interval.hours(1), Interval.hours(2)
	}, null);
	
	/**The task that updates task list (combo box) when selected project changes*/
	private TimerTask populateTask;

	public LogTimeForm(Vector projects, Task currentTask) {
		super("Log time");
		super.append(cmbProject);
		super.append(cmbTask);
		super.append(txtComment);
		super.append(cmbAlertAfter);
		
		super.addCommand(cmdOk);
		super.addCommand(cmdCancel);
		this.setProjects(projects, currentTask);

		// Select current task
		if (currentTask != null) {
			MainScreen.display.callSerially(new SelectIndex(cmbProject, cmbProject.indexOf(currentTask.getParent())));
			MainScreen.display.callSerially(new SelectIndex(cmbTask, cmbTask.indexOf(currentTask)));
		}
	}
	

	public void populateTasks() {
		populateTasks((Project) cmbProject.getSelectedObject());
	}
	
	public void populateTasks(Project p) {
		cmbTask.deleteAll();
		if (p != null) {
			for (Enumeration e = p.getTasks().elements(); e.hasMoreElements();) {
				Task task = (Task) e.nextElement();
				// Append only trackable tasks
				if (task.isTrackable())
					cmbTask.append(task, null);
			}
		}
	}

	public void setProjects(Vector projects, Task currentTask) {
		cmbProject.deleteAll();
		for (Enumeration e = projects.elements(); e.hasMoreElements();) {
			Project p = (Project) e.nextElement();
			if (p.getTrackableTasks().size() > 0)
				cmbProject.append(p, null);
		}
		// Initialize tasks
		if (currentTask != null)
			populateTasks(currentTask.getParent());
		else
			populateTasks();
	}
	
	/**
	 * Initializes the dialog with initial values before it is shown.
	 * @param comment
	 * @param isLogging
	 * @param currentTask
	 * @param alertAfter
	 */
	public void prepare(String comment, boolean isLogging, Task currentTask, long alertAfter) {
		this.txtComment.setString(comment);
		if (currentTask != null) {
			this.cmbProject.setselectedObject(currentTask.getParent());
			this.cmbTask.setselectedObject(currentTask);
		}
		this.cmbAlertAfter.setselectedObject(new Interval(alertAfter));
		// Schedule a timer that will populate tasks when project selection is changed
		populateTask = new TimerTask() {
			int selectedProject = -1;
			public void run() {
				try {
					if (selectedProject != LogTimeForm.this.cmbProject.getSelectedIndex()) {
						selectedProject = LogTimeForm.this.cmbProject.getSelectedIndex();
						populateTasks();
					}
				} catch (Exception e) {
					Helper.displayError("Error in LogTimeForm#populateTask", e);
				}
			}
		};
		timer.schedule(populateTask, 0, 300);
	}
	
	public void hide() {
		populateTask.cancel();
		timer.cancel();
	}

	public Task getTask() {
		return (Task) cmbTask.getSelectedObject();
	}

	public String getComment() {
		return txtComment.getString();
	}

	public long getInterval() {
		return ((Interval)cmbAlertAfter.getSelectedObject()).period;
	}

}
